package dev;

import com.alibaba.middleware.race.sync.Client;
import com.alibaba.middleware.race.sync.Constants2;
import io.netty.buffer.ByteBuf;
import net.DataHander;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

/**
 * Author :  Rocky
 * Date : 16/06/2017 15:32
 * Description :
 * Test :
 */
public class ClientDataHander implements DataHander {

    private static final Logger log = LoggerFactory.getLogger(Client.class);

    private FileChannel resultFile;

    public ClientDataHander() {
        try {
            resultFile = new RandomAccessFile(new File(Constants2.RESULT_HOME, Constants2.RESULT_FILE_NAME), "rw").getChannel();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void handleChangeRecord(ByteBuf changeRecordBuf) {

    }

    @Override
    public void handleRecordMeta(ByteBuf recordMeta) {
        //元数据解码
        RecordMeta.decode(recordMeta);
        RecordMeta.encodeFieldNames();

        log.info(RecordMeta.getInfo());
    }

    @Override
    public void getServerResultComplete() {
        log.info("server端发送结果数据完成");
        System.exit(-1);
    }

    private void writeToResultFile(ByteBuf resultBuf) {
        if (resultBuf.readableBytes() <= 0) {
            return;
        }
        try {
            resultFile.write(resultBuf.nioBuffer());
            resultBuf.clear();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void handlePkStartAndEnd(ByteBuf buf) {
        Constants2.pkStart = buf.readLong();
        Constants2.pkEnd = buf.readLong();
    }

    @Override
    public void handleServerResultData(ByteBuf serverResultDataBuf) {
        ByteBuf resultBuf = MiscUtils.directBuffer(Constants2.SEND_BUFFER_SIZE);

        while (serverResultDataBuf.readableBytes() > 0) {

            //读主键
            int pkValue = serverResultDataBuf.readInt();

            resultBuf.writeBytes((pkValue + "").getBytes());
            resultBuf.writeByte(9);

            for (int i = 1; i < RecordMeta.fieldsDataTypeList.size(); i++) {
                MapEntry entry = RecordMeta.fieldsDataTypeList.get(i);

                if (entry.getValue().equals(RecordMeta.NUM_DATA_TYPE)) {
                    resultBuf.writeBytes((serverResultDataBuf.readMedium() + "").getBytes());
                } else {

                    byte strByteSize = serverResultDataBuf.readByte();
                    byte[] strBytes = new byte[strByteSize];
                    serverResultDataBuf.readBytes(strBytes);

                    resultBuf.writeBytes(strBytes);
                }
                resultBuf.writeByte(9);
            }

            resultBuf.setByte(resultBuf.writerIndex() - 1, 10);
            if (resultBuf.readableBytes() < Constants2.SEND_BUFFER_SIZE) {
                continue;
            }
            writeToResultFile(resultBuf);
        }

        writeToResultFile(resultBuf);
    }

}
